﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
//MicroDesigner
using Jc.MicroDesigner.Exceptions;
using Jc.MicroDesigner.Management;
using Jc.MicroDesigner.Objects;
using Jc.MicroDesigner.Drawings;

namespace Jc.MicroDesigner.ElementsLib
{
    /// <summary>
    /// Элементы "генераторы"
    /// </summary>
    [DrawingToolItem("Генератор","Генераторы")]
    public class InElement : CircuitElement, ISignalGenerator
    {
        private SignalContainer _Signals = null;

        protected override PIN CreateSpecialPIN()
        {
            PIN pin = new PIN(_Name + "." + _PINCollection.Count.ToString(), this);
            pin.onRecieve += new Jc.MicroDesigner.Events.onRecieveHandler(pin_onRecieve);
            return pin;
        }

        void pin_onRecieve(PIN sender)
        {
            throw new IncorrectSignalException(this, sender, SignalType.In);
        }

        public InElement(ObjectManager manager)
            : base(manager, "input.xml") 
        {
            _Signals = new SignalContainer(this, ObjectManager.MaxTactCount);
            manager.Generators.Add(this);
        }

        /// <summary>
        /// Запустить такт
        /// </summary>
        /// <param name="signal">Сигнал</param>
        public void StartTact(sbyte signal)
        {
            _PINCollection[0].Send(signal);
        }

        public override void LoadAdditionals(Dictionary<ConfigSection, System.Xml.XmlNode> nodes)
        {
            // Загрузить сигналы  
            // Сигналы сохраняются для того, чтобы можно было воспроизводить поведение схемы после загрузки
            XmlNode add = nodes[ConfigSection.Additionals];
            XmlNode signals = add.ChildNodes[0];
            int i = 0;
            string sig_str = signals.Attributes["value"].Value;
            _Signals.Capacity = Math.Min(ObjectManager.MaxTactCount, sig_str.Length);
            while ((i < sig_str.Length) && (i < _Signals.Capacity))
            {
                _Signals[i] = SByte.Parse(sig_str[i].ToString());
                i++;
            }
        }

        public override void SaveAdditionals(Dictionary<ConfigSection, XmlNode> nodes)
        {
            //Сохранить сигналы одной строкой
            XmlNode add = nodes[ConfigSection.Additionals];
            XmlNode signal_node = add.OwnerDocument.CreateElement("signals");
            string signals = "";
            for (int i = 0; i < _Signals.Capacity; i++)
            {
                signals += _Signals[i].ToString();
            }
            SchemeSerializer.CreateXmlAttr(signal_node, "value", signals);
            add.AppendChild(signal_node);
        }

        #region ISignalGenerator Members

        public SignalContainer SignalsCollection
        {
            get { return _Signals; }
        }

        public void GenerateSignal(int time, int tact)
        {
            StartTact(_Signals[tact]);
        }

        public bool Editable
        {
            get { return true; }
        }

        #endregion
    }
}